import { ScaleSequential, scaleSequential } from "d3";
import { rgb, RGBColor } from "d3-color";
import { isUndefined } from "lodash-es";
import { transformColors } from "./util";

type GraphicsColors = {
  [name: string]: {
    ident: string;
    steps: number;
    default: {
      [key: number]: RGBColor;
    };
  };
};

type ScaleColors = {
  min: number;
  max: number;
  scaleColor: ScaleSequential<RGBColor, never>;
};
/**   rgb(110, 110, 110),
  rgb(110, 110, 110),
  rgb(110, 110, 110),
  rgb(117, 158, 137),
  rgb(127, 159, 159),
  rgb(131, 162, 162),
  rgb(134, 164, 164),
  rgb(136, 166, 166),
  rgb(140, 169, 169),
  rgb(187, 188, 188),*/
const graphicsColors: GraphicsColors = {
  TMP: {
    ident: "TMP",
    steps: 2048,
    default: {
      203: rgb(115, 70, 105, 255),
      218: rgb(202, 172, 195, 255),
      233: rgb(162, 70, 145, 255),
      248: rgb(143, 89, 169, 255),
      258: rgb(157, 219, 217, 255),
      265: rgb(106, 191, 181, 255),
      269: rgb(100, 166, 189, 255),
      273.15: rgb(93, 133, 198, 255),
      274: rgb(68, 125, 99, 255),
      283: rgb(128, 147, 24, 255),
      294: rgb(243, 183, 4, 255),
      303: rgb(232, 83, 25, 255),
      320: rgb(71, 14, 0, 255),
    },
  },
  POT: {
    ident: "POT",
    steps: 2048,
    default: {
      203: rgb(115, 70, 105, 255),
      218: rgb(202, 172, 195, 255),
      233: rgb(162, 70, 145, 255),
      248: rgb(143, 89, 169, 255),
      258: rgb(157, 219, 217, 255),
      265: rgb(106, 191, 181, 255),
      269: rgb(100, 166, 189, 255),
      273.15: rgb(93, 133, 198, 255),
      274: rgb(68, 125, 99, 255),
      283: rgb(128, 147, 24, 255),
      294: rgb(243, 183, 4, 255),
      303: rgb(232, 83, 25, 255),
      320: rgb(71, 14, 0, 255),
    },
  },
  TMAX: {
    ident: "TMAX",
    steps: 2048,
    default: {
      203: rgb(115, 70, 105, 255),
      218: rgb(202, 172, 195, 255),
      233: rgb(162, 70, 145, 255),
      248: rgb(143, 89, 169, 255),
      258: rgb(157, 219, 217, 255),
      265: rgb(106, 191, 181, 255),
      269: rgb(100, 166, 189, 255),
      273.15: rgb(93, 133, 198, 255),
      274: rgb(68, 125, 99, 255),
      283: rgb(128, 147, 24, 255),
      294: rgb(243, 183, 4, 255),
      303: rgb(232, 83, 25, 255),
      320: rgb(71, 14, 0, 255),
    },
  },
  TMIN: {
    ident: "TMIN",
    steps: 2048,
    default: {
      203: rgb(115, 70, 105, 255),
      218: rgb(202, 172, 195, 255),
      233: rgb(162, 70, 145, 255),
      248: rgb(143, 89, 169, 255),
      258: rgb(157, 219, 217, 255),
      265: rgb(106, 191, 181, 255),
      269: rgb(100, 166, 189, 255),
      273.15: rgb(93, 133, 198, 255),
      274: rgb(68, 125, 99, 255),
      283: rgb(128, 147, 24, 255),
      294: rgb(243, 183, 4, 255),
      303: rgb(232, 83, 25, 255),
      320: rgb(71, 14, 0, 255),
    },
  },
  DPT: {
    ident: "DPT",
    steps: 2048,
    default: {
      203: rgb(115, 70, 105, 255),
      218: rgb(202, 172, 195, 255),
      233: rgb(162, 70, 145, 255),
      248: rgb(143, 89, 169, 255),
      258: rgb(157, 219, 217, 255),
      265: rgb(106, 191, 181, 255),
      269: rgb(100, 166, 189, 255),
      273.15: rgb(93, 133, 198, 255),
      274: rgb(68, 125, 99, 255),
      283: rgb(128, 147, 24, 255),
      294: rgb(243, 183, 4, 255),
      303: rgb(232, 83, 25, 255),
      320: rgb(71, 14, 0, 255),
    },
  },
  WIND: {
    ident: "WIND",
    steps: 2048,
    default: {
      0: rgb(82, 71, 141, 0.42 * 255),
      10: rgb(80, 87, 184, 0.85 * 255),
      20: rgb(57, 136, 199, 0.85 * 255),
      30: rgb(75, 182, 152, 0.85 * 255),
      40: rgb(69, 206, 66, 0.85 * 255),
      50: rgb(149, 219, 70, 0.85 * 255),
      60: rgb(220, 234, 55, 0.85 * 255),
      70: rgb(235, 206, 53, 0.85 * 255),
      80: rgb(234, 164, 62, 0.85 * 255),
      90: rgb(233, 123, 72, 0.85 * 255),
      100: rgb(217, 66, 114, 0.85 * 255),
      110: rgb(175, 46, 90, 0.85 * 255),
      120: rgb(147, 23, 78, 0.93 * 255),
      130: rgb(99, 20, 22, 0.93 * 255),
      140: rgb(43, 0, 1, 255),
    },
  },
  VIS: {
    ident: "VIS",
    steps: 2048,
    default: {
      0: rgb(163, 89, 163),
      1600: rgb(161, 89, 163),
      2200: rgb(168, 86, 86),
      5e3: rgb(167, 86, 86),
      6e3: rgb(89, 97, 163),
      8e3: rgb(89, 101, 163),
      9e3: rgb(60, 188, 73),
      15e3: rgb(83, 167, 75),
      20004: rgb(110, 110, 110),
    },
  },
  RH: {
    ident: "RH",
    steps: 2048,
    default: {
      0: rgb(173, 85, 56),
      10: rgb(173, 85, 56),
      30: rgb(173, 110, 56),
      40: rgb(173, 146, 56),
      50: rgb(105, 173, 56),
      60: rgb(56, 173, 121),
      70: rgb(56, 174, 173),
      75: rgb(56, 160, 173),
      80: rgb(56, 157, 173),
      85: rgb(56, 148, 173),
      87: rgb(56, 135, 173),
      90: rgb(56, 132, 173),
      95: rgb(56, 123, 173),
      97: rgb(56, 98, 157),
      100: rgb(56, 70, 114),
    },
  },
  TCDC: {
    ident: "TCDC",
    steps: 2048,
    default: {
      0: rgb(157, 143, 87),
      40: rgb(117, 158, 137),
      50: rgb(105, 173, 56),
      60: rgb(127, 159, 159),
      70: rgb(131, 162, 162),
      75: rgb(134, 164, 164),
      80: rgb(136, 166, 166),
      // 85: rgb(56, 148, 173),
      // 87: rgb(56, 135, 173),
      90: rgb(140, 169, 169),
      // 95: rgb(56, 123, 173),
      // 97: rgb(56, 98, 157),
      100: rgb(187, 188, 188),
    },
  },
  APCP: {
    ident: "APCP",
    steps: 2048,
    default: {
      0: rgb(110, 110, 110, 1),
      0.1: rgb(82, 71, 141, 0.38),
      0.2: rgb(85, 78, 177, 0.5),
      0.5: rgb(67, 105, 196, 0.75),
      1: rgb(64, 160, 180, 0.87),
      2: rgb(78, 194, 98, 0.87),
      4: rgb(149, 219, 70, 0.87),
      6: rgb(220, 234, 55, 0.87),
      8: rgb(235, 192, 56, 0.87),
      10: rgb(234, 164, 62, 0.87),
      15: rgb(233, 123, 72, 0.87),
      20: rgb(225, 94, 93, 0.87),
      30: rgb(190, 48, 102, 0.87),
      40: rgb(147, 23, 78),
      50: rgb(84, 16, 41),
    },
  },
  ACPCP: {
    ident: "ACPCP",
    steps: 2048,
    default: {
      0: rgb(110, 110, 110, 1),
      0.1: rgb(82, 71, 141, 0.38),
      0.2: rgb(85, 78, 177, 0.5),
      0.5: rgb(67, 105, 196, 0.75),
      1: rgb(64, 160, 180, 0.87),
      2: rgb(78, 194, 98, 0.87),
      4: rgb(149, 219, 70, 0.87),
      6: rgb(220, 234, 55, 0.87),
      8: rgb(235, 192, 56, 0.87),
      10: rgb(234, 164, 62, 0.87),
      15: rgb(233, 123, 72, 0.87),
      20: rgb(225, 94, 93, 0.87),
      30: rgb(190, 48, 102, 0.87),
      40: rgb(147, 23, 78),
      50: rgb(84, 16, 41),
    },
  },
  PWAT: {
    ident: "PWAT",
    steps: 2048,
    default: {
      0: rgb(110, 110, 110, 1),
      0.1: rgb(82, 71, 141, 0.38),
      0.2: rgb(85, 78, 177, 0.5),
      0.5: rgb(67, 105, 196, 0.75),
      1: rgb(64, 160, 180, 0.87),
      2: rgb(78, 194, 98, 0.87),
      4: rgb(149, 219, 70, 0.87),
      6: rgb(220, 234, 55, 0.87),
      8: rgb(235, 192, 56, 0.87),
      10: rgb(234, 164, 62, 0.87),
      15: rgb(233, 123, 72, 0.87),
      20: rgb(225, 94, 93, 0.87),
      30: rgb(190, 48, 102, 0.87),
      40: rgb(147, 23, 78),
      50: rgb(84, 16, 41),
    },
  },
  SNOD: {
    ident: "SNOD",
    steps: 2048,
    default: {
      0: rgb(110, 110, 110),
      0.1: rgb(67, 97, 160),
      0.2: rgb(64, 113, 164),
      0.5: rgb(62, 139, 166),
      0.8: rgb(65, 163, 167),
      1.0: rgb(95, 154, 56),
      1.2: rgb(168, 169, 65),
      1.4: rgb(171, 134, 62),
      1.8: rgb(172, 95, 62),
      2.2: rgb(174, 62, 86),
      2.4: rgb(177, 60, 116),
      3.0: rgb(177, 60, 116),
    },
  },
  PRMSL: {
    ident: "PRMSL",
    steps: 4e3,
    default: {
      9e4: rgb(8, 16, 48, 255),
      95e3: rgb(0, 32, 96, 255),
      97600: rgb(0, 52, 146, 255),
      98600: rgb(0, 90, 148, 255),
      99500: rgb(0, 117, 146, 255),
      100200: rgb(26, 140, 147, 255),
      100700: rgb(103, 162, 155, 255),
      101125: rgb(155, 183, 172, 255),
      101325: rgb(182, 182, 182, 255),
      101525: rgb(176, 174, 152, 255),
      101900: rgb(167, 147, 107, 255),
      102400: rgb(163, 116, 67, 255),
      103e3: rgb(159, 81, 44, 255),
      103800: rgb(142, 47, 57, 255),
      104600: rgb(111, 24, 64, 255),
      108e3: rgb(48, 8, 24, 255),
    },
  },
  PRES: {
    ident: "PRES",
    steps: 0,
    default: {
      60000: rgb(242, 246, 144),
      76000: rgb(242, 246, 144),
      82000: rgb(242, 246, 144),
      88000: rgb(135, 210, 116),
      90000: rgb(83, 192, 132),
      94000: rgb(43, 167, 144),
      98000: rgb(40, 113, 147),
      100000: rgb(36, 60, 150),
      102000: rgb(35, 38, 102),
      104000: rgb(33, 16, 54),
      106000: rgb(33, 16, 54),
    },
  },
  LCDC: {
    ident: "LCDC",
    steps: 800,
    default: {
      0: rgb(156, 142, 87, 0.53),
      10: rgb(143, 131, 87, 0.59),
      30: rgb(129, 129, 129, 0.7),
      90: rgb(137, 159, 182, 0.9),
      100: rgb(187, 187, 187, 1),
    },
  },
  MCDC: {
    ident: "MCDC",
    steps: 800,
    default: {
      0: rgb(156, 142, 87, 0.53),
      10: rgb(143, 131, 87, 0.59),
      30: rgb(157, 192, 157, 0.7),
      90: rgb(145, 171, 145, 0.9),
      100: rgb(187, 187, 187, 1),
    },
  },
  HCDC: {
    ident: "HCDC",
    steps: 800,
    default: {
      0: rgb(156, 142, 87, 0.53),
      10: rgb(143, 131, 87, 0.59),
      30: rgb(125, 157, 157, 0.7),
      90: rgb(141, 169, 169, 0.9),
      100: rgb(187, 187, 187, 1),
    },
  },
  ALBDO: {
    ident: "HCDC",
    steps: 800,
    default: {
      0: rgb(110, 110, 110),
      10: rgb(0, 161, 247),
      15: rgb(0, 230, 0),
      20: rgb(0, 190, 0),
      25: rgb(0, 138, 0),
      30: rgb(255, 255, 0),
      35: rgb(240, 220, 0),
      40: rgb(255, 160, 0),
      45: rgb(254, 172, 172),
      50: rgb(254, 100, 92),
      55: rgb(238, 2, 48),
      60: rgb(235, 0, 195),
      65: rgb(155, 0, 185),
      70: rgb(173, 145, 241),
    },
  },
  CAPE: {
    ident: "CAPE",
    steps: 800,
    default: {
      0: rgb(110, 110, 110),
      350: rgb(110, 110, 110),
      400: rgb(93, 95, 127),
      500: rgb(37, 98, 145),
      800: rgb(37, 165, 37),
      1500: rgb(163, 161, 55),
      2000: rgb(155, 112, 63),
      2500: rgb(162, 55, 55),
      5001: rgb(151, 68, 151),
    },
  },
  SPFH: {
    ident: "SPFH",
    steps: 800,
    default: {
      0: rgb(110, 110, 110),
      0.001: rgb(110, 110, 110),
      0.002: rgb(155, 249, 174),
      0.005: rgb(8, 247, 121),
      0.01: rgb(0, 211, 72),
      0.015: rgb(0, 183, 48),
      0.02: rgb(0, 159, 38),
      0.025: rgb(0, 159, 38),
    },
  },
  TOZNE: {
    ident: "TOZNE",
    steps: 800,
    default: {
      0: rgb(53, 25, 47),
      150: rgb(61, 28, 54),
      220: rgb(108, 51, 122),
      280: rgb(83, 138, 205),
      330: rgb(79, 192, 175),
      400: rgb(167, 187, 5),
      450: rgb(177, 186, 0),
    },
  },
  REFC: {
    ident: "REFC",
    steps: 800,
    default: {
      0: rgb(110, 110, 110),
      10: rgb(24, 44, 168),
      15: rgb(0, 145, 148),
      20: rgb(70, 205, 96),
      25: rgb(195, 219, 38),
      30: rgb(245, 203, 8),
      35: rgb(244, 159, 33),
      40: rgb(223, 102, 68),
      45: rgb(190, 52, 94),
      50: rgb(190, 52, 94),
      60: rgb(157, 16, 109),
    },
  },
  GUST: {
    ident: "GUST",
    steps: 800,
    default: {
      0: rgb(98, 113, 184),
      3: rgb(61, 110, 163),
      5: rgb(74, 146, 148),
      8: rgb(76, 164, 76),
      10: rgb(103, 164, 54),
      12: rgb(162, 135, 64),
      15: rgb(162, 109, 92),
      18: rgb(141, 63, 92),
      20: rgb(151, 75, 145),
      25: rgb(95, 100, 160),
      30: rgb(91, 136, 161),
    },
  },
};

const getColors = (type: string) => {
  const el = graphicsColors[type];
  if (isUndefined(el))
    return console.error("Color doesn't exist"), () => rgb(255, 255, 255, 255);
  const defaultColors = Object.entries(el.default).sort(
    (a, b) => Number(a[0]) - Number(b[0])
  );
  // const steps = el.steps;
  const startStepColor = defaultColors[0];
  const endStepColor = defaultColors[defaultColors.length - 1];

  const scaleColors: ScaleColors[] = [];

  for (let i = 0; i < defaultColors.length - 1; i++) {
    const _startStep = defaultColors[i];
    const _endStep = defaultColors[i + 1];
    const [min, startColor] = _startStep;
    const [max, endColor] = _endStep;
    const scale = scaleSequential(
      [Number(min), Number(max)],
      [startColor, endColor]
    );
    scaleColors.push({
      min: Number(min),
      max: Number(max),
      scaleColor: scale,
    });
  }

  return function (value: number) {
    if (value < Number(startStepColor[0])) return startStepColor[1];
    if (value > Number(endStepColor[0])) return endStepColor[1];
    // if (value === 0) return rgb(110, 110, 110);

    const _scaleColor = scaleColors.find(
      ({ min, max }) => min <= value && max >= value
    )?.scaleColor;

    if (isUndefined(_scaleColor)) return rgb(255, 255, 255);
    return rgb(_scaleColor(value));
    // const stepIndex = defaultColors.findIndex(
    //   ([step]) => value <= Number(step)
    // );
    // const min = defaultColors[stepIndex - 1][0];
    // const max = defaultColors[stepIndex][0];
    // return rgb(
    //   scaleSequential(
    //     [Number(min), Number(max)],
    //     [defaultColors[stepIndex - 1][1], defaultColors[stepIndex][1]]
    //   )(value)
    // );
  };
};

const getLegendColors = (type: string) => {
  const el = graphicsColors[type];
  if (isUndefined(el))
    return (
      console.error("value doesn't exist"),
      transformColors([rgb(110, 110, 110), rgb(110, 110, 110)])
    );
  const values = Object.values(el.default);
  return transformColors(values);
};

const getFindMinMax = (type: string) => {
  const el = graphicsColors[type];
  if (isUndefined(el))
    return console.error("value doesn't exist"), { min: 0, max: 0 };
  const values = Object.entries(el.default).map(([step]) => Number(step));
  return {
    min: Math.min.call(Math.min, ...values),
    max: Math.max.call(Math.max, ...values),
  };
};

export { getColors, getFindMinMax, getLegendColors };
